import { useMemo, type ElementType } from 'react'
import { useQuery } from '@tanstack/react-query'
import dayjs from 'dayjs'
import { Link } from 'react-router-dom'

import { AnniversaryAPI, AIAPI, CycleAPI, DiaryAPI } from '../app/api'
import type { ApiAnniversary, ApiCyclePrediction, ApiDiaryEntry } from '../app/types'
import PageHeader from '../components/PageHeader'
import useCurrentUser from '../app/hooks/useCurrentUser'
import Button from '../components/ui/Button'
import { Card } from '../components/ui/Card'
import {
  BookOpenIcon,
  CalendarDaysIcon,
  HeartIcon,
  SparklesIcon,
  UserCircleIcon,
  UserGroupIcon,
} from '@heroicons/react/24/outline'
import { CursorArrowRaysIcon } from '@heroicons/react/24/outline'

const PHASE_LABELS: Record<string, string> = {
  menstruation: '月经期',
  follicular: '卵泡期',
  fertile: '排卵期',
  luteal: '黄体期',
}

const getPhaseLabel = (prediction: ApiCyclePrediction | undefined) => {
  if (!prediction) return undefined
  return prediction.phase_label ?? PHASE_LABELS[prediction.phase] ?? prediction.phase
}

const toTimestamp = (value?: string | null) => (value ? dayjs(value).valueOf() : 0)

const sortByDateDesc = <T extends { created_at?: string | null }>(list: T[]) =>
  [...list].sort((a, b) => toTimestamp(b.created_at) - toTimestamp(a.created_at))

const pickUpcoming = (anniversaries: ApiAnniversary[]) => {
  const today = dayjs().startOf('day')
  return anniversaries
    .map((item) => ({
      ...item,
      countdown: dayjs(item.date).startOf('day').diff(today, 'day'),
    }))
    .filter((item) => item.countdown >= 0)
    .sort((a, b) => a.countdown - b.countdown)
    .slice(0, 4)
}

const pickNextPrediction = (predictions: ApiCyclePrediction[]) => {
  if (predictions.length === 0) {
    return undefined
  }
  return [...predictions].sort((a, b) => dayjs(a.start_date).diff(dayjs(b.start_date)))[0]
}

const formatCountdown = (days: number) => {
  if (days === 0) return '今天'
  if (days === 1) return '明天'
  return `还有 ${days} 天`
}

const getGreeting = () => {
  const hour = dayjs().hour()
  if (hour < 6) return '凌晨好'
  if (hour < 11) return '早安'
  if (hour < 14) return '午间好'
  if (hour < 18) return '下午好'
  if (hour < 22) return '晚上好'
  return '夜深了'
}

const DashboardPage = () => {
  // Page title
  if (typeof document !== 'undefined') document.title = '仪表盘 · Love Notes'
  const { data: currentUser } = useCurrentUser()
  const diaryLimit = 6
  const { data: diaryPages, isLoading: diariesLoading } = useQuery({
    queryKey: ['diary', 'recent', diaryLimit],
    queryFn: () => DiaryAPI.list({ limit: diaryLimit }),
  })

  const { data: anniversaryPages, isLoading: anniversariesLoading } = useQuery({
    queryKey: ['anniversaries', 'recent', diaryLimit],
    queryFn: () => AnniversaryAPI.list({ limit: diaryLimit }),
  })

  const { data: predictions = [] } = useQuery({
    queryKey: ['cycle', 'predictions'],
    queryFn: CycleAPI.listPredictions,
  })

  const diaryItems = diaryPages?.items ?? []
  const anniversaryItems = anniversaryPages?.items ?? []

  const recentDiaries = useMemo(() => sortByDateDesc<ApiDiaryEntry>(diaryItems).slice(0, 3), [diaryItems])
  const upcomingAnniversaries = useMemo(() => pickUpcoming(anniversaryItems), [anniversaryItems])
  const nextPrediction = useMemo(() => pickNextPrediction(predictions), [predictions])
  const nextPhaseLabel = getPhaseLabel(nextPrediction)

  const aggregatedContext = useMemo(() => {
    if (recentDiaries.length === 0 && !upcomingAnniversaries[0] && !nextPrediction) {
      return ''
    }
    const diaryLines = recentDiaries
      .map((entry) => {
        const summary = entry.ai_summary ?? entry.content_md.slice(0, 120)
        return `${dayjs(entry.created_at ?? undefined).format('MM-DD')} ${entry.title}: ${summary}`
      })
      .join('\n')
    const anniversaryLine = upcomingAnniversaries[0]
      ? `最近纪念日：${upcomingAnniversaries[0].name}，${formatCountdown(upcomingAnniversaries[0].countdown)}`
      : ''
    const cycleLine = nextPrediction
      ? `周期阶段：${nextPhaseLabel ?? nextPrediction.phase} ${nextPrediction.start_date} ~ ${nextPrediction.end_date}`
      : ''
    return [diaryLines, anniversaryLine, cycleLine].filter(Boolean).join('\n')
  }, [recentDiaries, upcomingAnniversaries, nextPrediction, nextPhaseLabel])

  const suggestionTags = useMemo(() => {
    const tags = new Set<string>()
    recentDiaries.forEach((entry) => entry.tags.forEach((tag) => tags.add(tag)))
    if (nextPhaseLabel) tags.add(nextPhaseLabel)
    if (upcomingAnniversaries[0]?.name) tags.add(upcomingAnniversaries[0].name)
    return Array.from(tags).slice(0, 6)
  }, [recentDiaries, nextPhaseLabel, upcomingAnniversaries])

  const suggestionQuery = useQuery({
    queryKey: ['ai', 'dashboard-suggestion', aggregatedContext, suggestionTags.join('|')],
    enabled: Boolean(aggregatedContext),
    queryFn: () =>
      AIAPI.suggest({
        entry_context: aggregatedContext,
        mood: recentDiaries[0]?.mood ?? nextPhaseLabel ?? null,
        tags: suggestionTags,
      }),
    staleTime: 60_000,
  })

  const quickLinks: Array<{
    title: string
    description: string
    href: string
    icon: ElementType
    accent: string
  }> = [
    {
      title: '灵感抽签',
      description: '转盘/骰子快速决定吃穿玩，支持保存模板',
      href: '/randomizer',
      icon: CursorArrowRaysIcon,
      accent: 'from-rose-400 to-indigo-400',
    },
    {
      title: '恋爱日记',
      description: '写下今天的故事与心情，支持 AI 辅助创作',
      href: '/diary',
      icon: BookOpenIcon,
      accent: 'from-blush-500 to-lavender-400',
    },
    {
      title: '纪念日',
      description: '管理重要日子与提醒，让仪式感有迹可循',
      href: '/anniversaries',
      icon: CalendarDaysIcon,
      accent: 'from-lavender-500 to-violet-400',
    },
    {
      title: '生理周期',
      description: '记录每日状态，查看下一次周期预测',
      href: '/cycle',
      icon: HeartIcon,
      accent: 'from-sky-500 to-lavender-400',
    },
    {
      title: 'AI 助手',
      description: '让情感教练从数据出发，提供贴心建议',
      href: '/assistant',
      icon: SparklesIcon,
      accent: 'from-amber-400 to-blush-400',
    },
    {
      title: '记忆图谱',
      description: '将偏好、提醒、约定与话题串成关系网络',
      href: '/assistant/graph',
      icon: SparklesIcon,
      accent: 'from-emerald-400 to-amber-300',
    },
    {
      title: '情侣匹配',
      description: '生成邀请码或加入伴侣空间，共享数据',
      href: '/relationships',
      icon: UserGroupIcon,
      accent: 'from-emerald-400 to-cyan-400',
    },
    {
      title: '我的',
      description: '维护双方档案、通知偏好与帐号安全',
      href: '/profile',
      icon: UserCircleIcon,
      accent: 'from-slate-500 to-slate-400',
    },
  ]

  const metrics = [
    {
      label: '恋爱日记',
      value: diaryItems.length.toString(),
      description:
        diaryItems.length > 0 ? `最新更新于 ${dayjs(diaryItems[0]?.created_at).format('MM-DD HH:mm')}` : '还没有记录',
      accent: 'from-blush-400 to-lavender-400',
    },
    {
      label: '即将纪念日',
      value: upcomingAnniversaries.length.toString(),
      description: upcomingAnniversaries[0]
        ? `${upcomingAnniversaries[0].name} · ${formatCountdown(upcomingAnniversaries[0].countdown)}`
        : '暂无即将到来的纪念日',
      accent: 'from-lavender-400 to-violet-400',
    },
    {
      label: '周期提醒',
      value: nextPrediction ? nextPhaseLabel ?? '暂无' : '暂无',
      description: nextPrediction
        ? `${nextPrediction.start_date} ~ ${nextPrediction.end_date}`
        : '等待记录同步',
      accent: 'from-sky-400 to-cyan-400',
    },
    {
      label: '爱之标签',
      value: suggestionTags.length.toString(),
      description: suggestionTags.length > 0 ? suggestionTags.map((tag) => `#${tag}`).join(' · ') : '暂无标签',
      accent: 'from-rose-400 to-amber-300',
    },
  ]

  const moments = useMemo(() => {
    const items: Array<{ id: string; title: string; detail: string; accent: string }> = []
    upcomingAnniversaries.forEach((event) =>
      items.push({
        id: `anniversary-${event.id}`,
        title: `${event.name}`,
        detail: formatCountdown(event.countdown),
        accent: 'ring-1 ring-lavender-500/40',
      }),
    )
    if (nextPrediction) {
      items.push({
        id: `cycle-${nextPrediction.phase}`,
        title: `周期阶段：${nextPhaseLabel ?? nextPrediction.phase}`,
        detail: `${nextPrediction.start_date} ~ ${nextPrediction.end_date}`,
        accent: 'ring-1 ring-sky-400/40',
      })
    }
    recentDiaries.slice(0, 2).forEach((entry) =>
      items.push({
        id: `diary-${entry.id}`,
        title: entry.title,
        detail: entry.mood ? `心情 ${entry.mood}` : dayjs(entry.created_at).format('MM-DD'),
        accent: 'ring-1 ring-blush-400/40',
      }),
    )
    return items.slice(0, 6)
  }, [upcomingAnniversaries, nextPrediction, nextPhaseLabel, recentDiaries])

  const greeting = getGreeting()
  const heroMood = recentDiaries[0]?.mood ?? nextPhaseLabel ?? '温度适中'

  const displayName = currentUser?.nickname || currentUser?.username || ''

  return (
    <div className="space-y-8">
      <PageHeader
        eyebrow="Overview"
        title={`${getGreeting()}，${displayName || '欢迎回来'}`}
        description="用一眼的时间掌握你们的心情脉络、纪念日节奏与生理周期状态。"
        actions={
          <div className="flex flex-wrap gap-2">
            <Button as="a" href="/assistant" variant="secondary" size="sm">
              打开 AI 助手
            </Button>
            <Button as="a" href="/diary" variant="primary" size="sm">
              记录今日心情
            </Button>
          </div>
        }
      />

      <section className="space-y-3">
        <header className="flex items-end justify-between">
          <div>
            <h2 className="text-sm font-semibold text-slate-900">快捷操作</h2>
            <p className="text-xs text-slate-500">缩短抵达路径，让常用功能触手可及。</p>
          </div>
        </header>
        <div className="grid grid-cols-3 gap-3 min-[420px]:grid-cols-4 sm:grid-cols-6">
          {quickLinks.map((link) => (
            <QuickLinkCard key={link.title} {...link} />
          ))}
        </div>
      </section>

      <section className="space-y-3">
        <header className="flex items-end justify-between">
          <div>
            <h2 className="text-sm font-semibold text-slate-900">关系体征</h2>
            <p className="text-xs text-slate-500">浓缩趋势指标，放入口袋里的小小仪表盘。</p>
          </div>
        </header>
        <div className="grid grid-cols-2 gap-3 md:grid-cols-4">
          {metrics.map((metric) => (
            <MetricTile key={metric.label} {...metric} />
          ))}
        </div>
      </section>

      <section className="space-y-3">
        <header className="flex items-center justify-between">
          <h2 className="text-sm font-semibold text-slate-900">今日焦点</h2>
          <span className="text-xs text-slate-400">左右滑动查看更多</span>
        </header>
        <div className="flex gap-3 overflow-x-auto pb-1">
          {moments.length > 0 ? (
            moments.map((moment) => <MomentChip key={moment.id} {...moment} />)
          ) : (
            <div className="flex h-20 w-full items-center justify-center rounded-2xl border border-dashed border-slate-200 bg-slate-50/70 text-xs text-slate-400">
              记录更多内容，我们会为你挑选今日焦点。
            </div>
          )}
        </div>
      </section>

      <section className="grid gap-6 xl:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]">
        <Card
          title="共享瞬间"
          description="交替排布的日记片段，保留心情质感。"
          padding="sm"
          actions={
            <Button as="a" href="/diary" variant="secondary" size="sm">
              管理日记
            </Button>
          }
        >
          {diariesLoading ? (
            <p className="text-sm text-slate-400">日记加载中...</p>
          ) : recentDiaries.length === 0 ? (
            <EmptyState message="还没有日记记录，开始记录第一篇吧。" />
          ) : (
            <div className="grid gap-4 sm:grid-cols-2">
              {recentDiaries.map((entry, index) => (
                <article
                  key={entry.id}
                  className={`group relative overflow-hidden surface-card border border-white/20 p-4 transition hover:-translate-y-1 ${
                    index === 0 ? 'sm:col-span-2 sm:flex sm:items-end sm:justify-between sm:gap-4' : ''
                  }`}
                >
                  <div className="space-y-2">
                    <div className="flex items-center justify-between gap-2">
                      <p className="text-base font-semibold text-slate-900">{entry.title}</p>
                      {entry.mood ? (
                        <span className="badge-soft bg-blush-100/90 text-blush-500">心情：{entry.mood}</span>
                      ) : null}
                    </div>
                    <p className="text-xs text-slate-400">
                      {entry.created_at ? dayjs(entry.created_at).format('YYYY-MM-DD HH:mm') : '时间未知'}
                    </p>
                    <p className="text-sm leading-relaxed text-slate-600">
                      {entry.ai_summary ?? entry.content_md.slice(0, 120)}
                    </p>
                    {(entry.tags?.length ?? 0) > 0 ? (
                      <div className="flex flex-wrap gap-2">
                        {(entry.tags ?? []).map((tag) => (
                          <span key={tag} className="badge">
                            #{tag}
                          </span>
                        ))}
                      </div>
                    ) : null}
                  </div>
                  <div className="pointer-events-none absolute -right-8 -top-6 h-20 w-20 rounded-full bg-blush-100/60 blur-2xl transition group-hover:bg-blush-200/50" />
                </article>
              ))}
            </div>
          )}
        </Card>

        <div className="space-y-6">
          <Card
            title="纪念日与提醒"
            description="不要错过任何一个值得庆祝的节点。"
            padding="sm"
            actions={
              <Button as="a" href="/anniversaries" variant="secondary" size="sm">
                管理纪念日
              </Button>
            }
          >
            {anniversariesLoading ? (
              <p className="text-sm text-slate-400">纪念日加载中...</p>
            ) : upcomingAnniversaries.length === 0 ? (
              <EmptyState message="暂无即将到来的纪念日。" />
            ) : (
              <div className="space-y-3">
                {upcomingAnniversaries.map((event) => (
                  <article
                    key={event.id}
                    className="flex items-center justify-between gap-3 rounded-3xl border border-slate-100 bg-slate-50/70 px-4 py-3 text-sm text-slate-600"
                  >
                    <div>
                      <p className="font-semibold text-slate-900">{event.name}</p>
                      <p className="text-xs text-slate-400">{dayjs(event.date).format('YYYY-MM-DD')}</p>
                    </div>
                    <div className="text-right">
                      <span className="badge-soft mb-1 block">{formatCountdown(event.countdown)}</span>
                      <p className="text-[11px] text-slate-400">提前 {event.reminder_offset_days} 天提醒</p>
                    </div>
                  </article>
                ))}
              </div>
            )}
          </Card>

          <Card title="小蛋建议" description="每天早上 6 点基于双方数据生成，不重复打扰。" padding="sm">
            {suggestionQuery.isPending ? (
              <p className="text-sm text-slate-400">生成建议中...</p>
            ) : suggestionQuery.data ? (
              <div className="solid-panel overflow-hidden p-5">
                <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
                  <div className="space-y-2">
                    <p className="text-xs uppercase tracking-[0.2em] text-slate-400">今日提问</p>
                    <p className="text-base font-semibold text-slate-900">{suggestionQuery.data.message}</p>
                    {suggestionQuery.data.tags.length > 0 ? (
                      <div className="mt-2 flex flex-wrap gap-2 text-xs text-slate-500">
                        {suggestionQuery.data.tags.map((tag) => (
                          <span key={tag} className="badge">
                            #{tag}
                          </span>
                        ))}
                      </div>
                    ) : null}
                  </div>
                  <Button as="a" href="/assistant" variant="ghost" size="sm">
                    开始对话
                  </Button>
                </div>
                <div className="pointer-events-none absolute -bottom-14 right-0 h-32 w-32 rounded-full bg-blush-200/70 blur-2xl" />
              </div>
            ) : (
              <EmptyState message="暂无可生成的建议，先记录几篇日记或补充纪念日信息吧。" />
            )}
          </Card>

        </div>
      </section>
    </div>
  )
}

const MetricTile = ({
  label,
  value,
  description,
  accent,
}: {
  label: string
  value: string
  description: string
  accent: string
}) => (
  <article className="group relative flex aspect-square flex-col justify-between overflow-hidden surface-card border border-white/20 p-4 transition hover:-translate-y-1">
    <div className="flex items-center justify-between">
      <p className="text-[10px] uppercase tracking-[0.15em] text-slate-400">{label}</p>
      <span className={`h-2 w-10 rounded-full bg-gradient-to-r ${accent} opacity-80`} />
    </div>
    <p className="text-2xl font-semibold text-slate-900">{value}</p>
    <p className="text-[11px] leading-relaxed text-slate-500">{description}</p>
    <div className={`pointer-events-none absolute -right-6 top-6 h-16 w-16 rounded-full bg-gradient-to-br ${accent} opacity-30 blur-2xl transition group-hover:opacity-60`} />
  </article>
)

const MomentChip = ({ title, detail, accent }: { title: string; detail: string; accent: string }) => (
  <div
    className={`flex min-w-[160px] flex-col justify-between surface-card border border-white/20 px-4 py-3 text-sm transition hover:-translate-y-1 ${accent}`}
  >
    <p className="font-medium text-slate-900">{title}</p>
    <p className="mt-2 text-xs text-slate-400">{detail}</p>
  </div>
)

const EmptyState = ({ message }: { message: string }) => (
  <div className="rounded-2xl border border-dashed border-slate-200 bg-slate-50/70 px-4 py-6 text-center text-sm text-slate-500">
    {message}
  </div>
)

const QuickLinkCard = ({
  title,
  description,
  href,
  icon: Icon,
  accent,
}: {
  title: string
  description: string
  href: string
  icon: ElementType
  accent: string
}) => (
  <Link to={href} className="group flex flex-col items-center gap-2 text-center" title={description}>
    <span
      className={`flex h-14 w-14 items-center justify-center rounded-full bg-gradient-to-br ${accent} text-white shadow-card transition group-hover:-translate-y-1 group-hover:shadow-lg`}
    >
      <Icon className="h-5 w-5" />
    </span>
    <span className="text-[11px] font-medium text-slate-600 group-hover:text-slate-900">{title}</span>
  </Link>
)

export default DashboardPage
